/*
 * Copyright (C) 2004, Velocityme Partnership
 * RemoteClientSessionBean.java
 *
 * Created on 20 May 2004, 11:23
 */

package com.velocityme.session;

import javax.ejb.*;
import javax.naming.*;
import java.util.*;

import com.velocityme.interfaces.*;
import com.velocityme.utility.DuplicateUserException;
import com.velocityme.utility.InvalidKeyException;
import com.velocityme.utility.InvalidTimeException;
import com.velocityme.utility.PasswordIncorrectException;
import com.velocityme.utility.PermissionDeniedException;
import com.velocityme.valueobjects.*;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.RemoteException;

/**
 *
 * @author  Robert
 * @ejb.bean
 *           type="Stateless"
 *           cmp-version="2.x"
 *           name="RemoteClientSession"
 *           jndi-name="ejb/RemoteClientSession"
 *           view-type="both"
 *           transaction-type="Container"
 * @ejb.transaction type="Required"
 *
 * @ejb.util generate="physical"
 */
public class RemoteClientSessionBean implements SessionBean {
    
    private SessionContext m_context;
    /**
     * Get a local key given a handle to a remote key. This method must ensure
     * that the local key is valid otherwise it throws InvalidKeyException
     *
     * @param p_key the remote key
     */
    private KeySessionLocal getKeyLocal(KeySession p_key) throws InvalidKeyException {
        if (p_key == null)
            throw new InvalidKeyException();
        try {
            return p_key.getLocal();
        }
        catch(Exception e) {
            throw new InvalidKeyException();
        }
    }
    
    /**
     * If the user has permission to create a new Action in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNodePK The node which will contain the new Action
     * @param p_actionValue The value details for the Action part of the action
     *
     * @ejb.interface-method view-type="remote"
     **/
    public ActionPK actionCreate(KeySession p_key,
                                 NodePK p_parentNodePK,
                                 com.velocityme.valueobjects.ActionValue p_actionValue) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            ActionLocal actionLocal = ActionSessionUtil.getLocalHome().create().createAction(keyLocal, parentNodeLocal, p_actionValue);
            return new ActionPK(actionLocal.getActionId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the action then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_action The Action object being editted
     * @param p_actionValue The value details for the Action part of the action
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void actionEdit(KeySession p_key, 
                           ActionPK p_actionPK,
                           com.velocityme.valueobjects.ActionValue p_actionValue,
                           com.velocityme.interfaces.ContactablePK[] p_responsibleContactablePKs,
                           com.velocityme.interfaces.ContactablePK[] p_interestedContactablePKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            ActionLocal actionLocal = ActionUtil.getLocalHome().findByPrimaryKey(p_actionPK);
            Collection responsibleContactableLocals = new ArrayList();
            for (int i = 0; i < p_responsibleContactablePKs.length; i++)
                responsibleContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_responsibleContactablePKs[i]));
            Collection interestedContactableLocals = new ArrayList();
            for (int i = 0; i < p_interestedContactablePKs.length; i++)
                interestedContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_interestedContactablePKs[i]));
            ActionSessionUtil.getLocalHome().create().editAction(keyLocal, actionLocal, p_actionValue, responsibleContactableLocals, interestedContactableLocals);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the action value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_actionPK The Action primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.ActionValue getActionValue(KeySession p_key,
                                                                  ActionPK p_actionPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            ActionLocal actionLocal = ActionSessionUtil.getLocalHome().create().getActionLocal(getKeyLocal(p_key), p_actionPK);
            return actionLocal.getActionValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Anchor in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNodePK The node which will contain the new Anchor
     * @param p_anchorValue The value details for the Anchor part of the anchor
     *
     * @ejb.interface-method view-type="remote"
     **/
    public AnchorPK anchorCreate(KeySession p_key,
                                 NodePK p_parentNodePK,
                                 com.velocityme.valueobjects.AnchorValue p_anchorValue) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            AnchorLocal anchorLocal = AnchorSessionUtil.getLocalHome().create().createAnchor(keyLocal, parentNodeLocal, p_anchorValue);
            return new AnchorPK(anchorLocal.getAnchorId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the anchor then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_anchor The Anchor object being editted
     * @param p_anchorValue The value details for the Anchor part of the anchor
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void anchorEdit(KeySession p_key, 
                           AnchorPK p_anchorPK,
                           com.velocityme.valueobjects.AnchorValue p_anchorValue,
                           com.velocityme.interfaces.ContactablePK[] p_responsibleContactablePKs,
                           com.velocityme.interfaces.ContactablePK[] p_interestedContactablePKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            AnchorLocal anchorLocal = AnchorUtil.getLocalHome().findByPrimaryKey(p_anchorPK);
            Collection responsibleContactableLocals = new ArrayList();
            for (int i = 0; i < p_responsibleContactablePKs.length; i++)
                responsibleContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_responsibleContactablePKs[i]));
            Collection interestedContactableLocals = new ArrayList();
            for (int i = 0; i < p_interestedContactablePKs.length; i++)
                interestedContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_interestedContactablePKs[i]));
            AnchorSessionUtil.getLocalHome().create().editAnchor(keyLocal, anchorLocal, p_anchorValue, responsibleContactableLocals, interestedContactableLocals);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the anchor value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_anchorPK The Anchor primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.AnchorValue getAnchorValue(KeySession p_key,
                                                                  AnchorPK p_anchorPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            AnchorLocal anchorLocal = AnchorSessionUtil.getLocalHome().create().getAnchorLocal(getKeyLocal(p_key), p_anchorPK);
            return anchorLocal.getAnchorValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the task value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.TaskValue getTaskValue(KeySession p_key,
                                                              TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid())
                return TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK).getTaskValue();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then determine if the task corresponding to 
     * the specified primary key is active (ie in the state machine).
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isTaskActive(KeySession p_key,
                                TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            return TaskSessionUtil.getLocalHome().create().isActive(getKeyLocal(p_key), taskLocal);                
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get all the state value object corresponding
     * to the specified task primary key.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StateValue[] getTaskStateValues(KeySession p_key,
                                                                       TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            return StateSessionUtil.getLocalHome().create().getTaskStateValueObjects(keyLocal, taskLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the collection of responsible
     * contactables by value for the specified task primary key.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public Collection getTaskResponsibleContactableValues(KeySession p_key,
                                                          TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid())
                return TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK).getResponsibleContactablesValue();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the collection of interested
     * contactables by value for the specified task primary key.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public Collection getTaskInterestedContactableValues(KeySession p_key,
                                                         TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid())
                return TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK).getInterestedContactablesValue();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key set the interested status of the task with
     * the specified task primary key for the current user.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskToggleInterestedContactableStateValue(KeySession p_key,
                                                          TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keySessionLocal = getKeyLocal(p_key);
            if (keySessionLocal.isValid()) {
                TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
                TaskSessionUtil.getLocalHome().create().toggleInterestedState(keySessionLocal, taskLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key set the interested status of the task with
     * the specified task primary key for the current user.
     *
     * @param p_key User's security key
     * @param p_taskPK The Task primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskEnableInterestedContactableStateValue(KeySession p_key,
                                                          TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keySessionLocal = getKeyLocal(p_key);
            if (keySessionLocal.isValid()) {
                TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
                TaskSessionUtil.getLocalHome().create().enableInterestedState(keySessionLocal, taskLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of contact detail type value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllContactDetailValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return ContactDetailSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the directory DTO with all information from the directory for the
     * user of the specified key
     *
     * @param p_key User's security key
     * @return the directory DTO
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.utility.DirectoryDTO getDirectoryDTO(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return ContactableSessionUtil.getLocalHome().create().getDirectoryDTO(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of notification mechanism type value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.NotificationMechanismValue[] getAllNotificationMechanismValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return NotificationMechanismSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Sets up the table of contact detail types. Value objects with valid IDs
     * will be edited. Those without valid IDs are new and will be created.
     * Existing types that are not in the collection will be deleted. Note that
     * all contact details of the types deleted will be deleted too.
     *
     * @param p_key User's security key
     * @param p_values Collection of contact detail type value objects
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void setContactDetailTypeValues(KeySession p_key, java.util.Collection p_values) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            ContactDetailSessionUtil.getLocalHome().create().setContactDetailTypeValueObjects(keyLocal, p_values);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of system property value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllSystemPropertyValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return SystemPropertySessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Sets up the table of system properties. Value objects with valid IDs
     * will be edited. Those without valid IDs are new and will be created.
     * Existing types that are not in the collection will be deleted.
     *
     * @param p_key User's security key
     * @param p_values Collection of system property value objects
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void setSystemPropertyValues(KeySession p_key, java.util.Collection p_values) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SystemPropertySessionUtil.getLocalHome().create().setSystemPropertyValueObjects(keyLocal, p_values);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the change log report for the specified DB Object if the key is valid
     *
     * @param p_key User's security key
     * @param p_dbObjectPK DB object primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String getDBObjectChangeLogXML(KeySession p_key,
                                                    DBObjectPK p_dbObjectPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            if (keyLocal.isValid())
                return DBObjectUtil.getLocalHome().findByPrimaryKey(p_dbObjectPK).getChangeLogXML();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);           
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the change log values for the specified DB Object if the key is valid
     *
     * @param p_key User's security key
     * @param p_dbObjectPK DB object primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getDBObjectChangeDeltaValues(KeySession p_key,
                                                             DBObjectPK p_dbObjectPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            if (keyLocal.isValid()) {
                DBObjectLocal dBObjectLocal = DBObjectUtil.getLocalHome().findByPrimaryKey(p_dbObjectPK);
                Collection changeDeltaLocals = dBObjectLocal.getChangeDeltasLocal();
                Collection changeDeltaValues = new ArrayList();
                Iterator i = changeDeltaLocals.iterator();
                while(i.hasNext()) {
                    ChangeDeltaLocal changeDeltaLocal = (ChangeDeltaLocal)i.next();
                    changeDeltaValues.add(changeDeltaLocal.getChangeDeltaValue());
                }
                return changeDeltaValues;
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);           
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get a tree model of all the contactable entities in the database
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public javax.swing.tree.TreeModel getContactableValueTree(com.velocityme.interfaces.KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return ContactableSessionUtil.getLocalHome().create().getContactableValueTree(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the contactable value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_contactablePK The Action primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.ContactableValue getContactableValue(KeySession p_key,
                                                                            ContactablePK p_contactablePK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid())
                return ContactableUtil.getLocalHome().findByPrimaryKey(p_contactablePK).getContactableValue();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Department in the specified 
     * parentnode then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNodePK The node which will contain the new Department
     * @param p_departmentValue The value details for the Department part of the department
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.DepartmentPK departmentCreate(KeySession p_key,
                                                                   NodePK p_parentNodePK,
                                                                   com.velocityme.valueobjects.DepartmentValue p_departmentValue) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            DepartmentLocal departmentLocal = DepartmentSessionUtil.getLocalHome().create().createDepartment(keyLocal, parentNodeLocal, p_departmentValue);
            return new DepartmentPK(departmentLocal.getDepartmentId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the department then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_department The Department object being edited
     * @param p_departmentValue The value details for the Department part of the department
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void departmentEdit(KeySession p_key,
                               DepartmentPK p_departmentPK,
                               com.velocityme.valueobjects.DepartmentValue p_departmentValue) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            DepartmentLocal departmentLocal = DepartmentUtil.getLocalHome().findByPrimaryKey(p_departmentPK);
            DepartmentSessionUtil.getLocalHome().create().editDepartment(keyLocal, departmentLocal, p_departmentValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of department value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllDepartmentValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return DepartmentSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the department value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_departmentPK The Department primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.DepartmentValue getDepartmentValue(KeySession p_key,
                                                                          DepartmentPK p_departmentPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            DepartmentLocal departmentLocal = DepartmentSessionUtil.getLocalHome().create().getDepartmentLocal(getKeyLocal(p_key), p_departmentPK);
            DepartmentValue departmentValue = departmentLocal.getDepartmentValueQualified();
            ContactableValueToString.sortContactDetails(departmentValue.getContactableValue());
            return departmentValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the qualified name of the department specified
     *
     * @param p_departmentPK The Department primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String getDepartmentQualifiedName(DepartmentPK p_departmentPK) {
        try {
            DepartmentLocal departmentLocal = DepartmentUtil.getLocalHome().findByPrimaryKey(p_departmentPK);
            return departmentLocal.getQualifiedName();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Issue in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Issue
     * @param p_issueValue The value details for the Issue part of the issue
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.IssuePK issueCreate(KeySession p_key,
                                                         NodePK p_parentNodePK,
                                                         com.velocityme.valueobjects.IssueValue p_issueValue) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            IssueLocal issueLocal = IssueSessionUtil.getLocalHome().create().createIssue(keyLocal, parentNodeLocal, p_issueValue);
            return new IssuePK(issueLocal.getIssueId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to moderate the issue then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_issue The Issue object being editted
     * @param p_issueValue The value details for the Issue part of the issue
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void issueEdit(KeySession p_key, 
                          IssuePK p_issuePK,
                          com.velocityme.valueobjects.IssueValue p_issueValue,
                          com.velocityme.interfaces.ContactablePK[] p_responsibleContactablePKs,
                          com.velocityme.interfaces.ContactablePK[] p_interestedContactablePKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            IssueLocal issueLocal = IssueUtil.getLocalHome().findByPrimaryKey(p_issuePK);
            Collection responsibleContactableLocals = new ArrayList();
            for (int i = 0; i < p_responsibleContactablePKs.length; i++)
                responsibleContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_responsibleContactablePKs[i]));
            Collection interestedContactableLocals = new ArrayList();
            for (int i = 0; i < p_interestedContactablePKs.length; i++)
                interestedContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_interestedContactablePKs[i]));
            IssueSessionUtil.getLocalHome().create().editIssue(keyLocal, issueLocal, p_issueValue, responsibleContactableLocals, interestedContactableLocals);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the issue value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_issuePK The Action primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.IssueValue getIssueValue(KeySession p_key,
                                                                IssuePK p_issuePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            IssueLocal issueLocal = IssueSessionUtil.getLocalHome().create().getIssueLocal(getKeyLocal(p_key), p_issuePK);
            return issueLocal.getIssueValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Node in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Node
     * @param p_nodeValue The value details for the Node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public NodePK nodeCreate(com.velocityme.interfaces.KeySession p_key,
                             com.velocityme.interfaces.NodePK p_parentNodePK,
                             com.velocityme.valueobjects.NodeValue p_nodeValue,
                             java.lang.String p_finalType)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            NodeLocal nodeLocal = NodeSessionUtil.getLocalHome().create().createNode(keyLocal, parentNodeLocal, p_nodeValue, p_finalType);
            return new NodePK(nodeLocal.getNodeId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the Node then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_node The Node object being edited
     * @param p_nodeValue The value details for the Node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void nodeEdit(com.velocityme.interfaces.KeySession p_key,
                         com.velocityme.interfaces.NodePK p_nodePK,
                         com.velocityme.valueobjects.NodeValue p_nodeValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            NodeSessionUtil.getLocalHome().create().editNode(keyLocal, nodeLocal, p_nodeValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to post a comment in the specified node then
     * put the message into the change log
     *
     * @param p_key User's security key
     * @param p_nodePK The node which will contain the message
     * @param p_message The message for the change log
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void nodePostComment(com.velocityme.interfaces.KeySession p_key,
                                com.velocityme.interfaces.NodePK p_nodePK,
                                java.lang.String p_message,
                                java.io.File p_file,
                                java.lang.String p_contentType,
                                java.io.InputStream p_stream)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            NodeSessionUtil.getLocalHome().create().postComment(keyLocal, nodeLocal, p_message, p_file, p_contentType, p_stream);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to delete the specified node then
     * put the message into the change log
     *
     * @param p_key User's security key
     * @param p_nodePK The node which will be deleted
     * @return the parent nodePK
     *
     * @ejb.interface-method view-type="remote"
     **/
    public NodePK nodeDelete(com.velocityme.interfaces.KeySession p_key,
                             com.velocityme.interfaces.NodePK p_nodePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            NodeLocal parentNodeLocal = NodeSessionUtil.getLocalHome().create().deleteNode(keyLocal, nodeLocal);
            return new NodePK(parentNodeLocal.getNodeId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the node value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_nodePK The Node primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.NodeValue getNodeValue(KeySession p_key,
                                                              NodePK p_nodePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            NodeLocal nodeLocal = NodeSessionUtil.getLocalHome().create().getNodeLocal(getKeyLocal(p_key), p_nodePK);
            return nodeLocal.getNodeValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to view the node then get the history.
     *
     * @param p_key User's security key
     * @param p_nodePK The Node primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.utility.SearchEntry getHistoryValue(KeySession p_key,
                                                              NodePK p_nodePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            NodeLocal nodeLocal = NodeSessionUtil.getLocalHome().create().getNodeLocal(getKeyLocal(p_key), p_nodePK);
            return NodeSessionUtil.getLocalHome().create().getHistoryValue(getKeyLocal(p_key), nodeLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then lookup the file attachment value.
     *
     * @param p_key User's security key
     * @param p_uniqueName The file attachment's unique name
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.FileAttachmentValue findFileAttachmentValue(KeySession p_key,
                                                                                   String p_serverName)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (p_key.isValid()) {
                FileAttachmentLocal fileAttachmentLocal = FileAttachmentUtil.getLocalHome().findByServerName(p_serverName);
                return fileAttachmentLocal.getFileAttachmentValue();
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
        catch(IOException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the length of the attachment
     * contents.
     *
     * @param p_key User's security key
     * @param p_fileAttachmentPK The file attachment's primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public long getFileAttachmentLength(KeySession p_key,
                                        com.velocityme.interfaces.FileAttachmentPK p_fileAttachmentPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (p_key.isValid()) {
                FileAttachmentLocal fileAttachmentLocal = FileAttachmentUtil.getLocalHome().findByPrimaryKey(p_fileAttachmentPK);
                return FileAttachmentSessionUtil.getLocalHome().create().fileAttachmentLength(fileAttachmentLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
        catch(FileNotFoundException e) {
            throw new EJBException(e);
        }
        catch(IOException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get an input stream to read the attachment
     * contents.
     *
     * @param p_key User's security key
     * @param p_uniqueName The file attachment's unique name
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.io.BufferedInputStream getFileAttachmentInputStream(KeySession p_key,
                                                                    com.velocityme.interfaces.FileAttachmentPK p_fileAttachmentPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (p_key.isValid()) {
                FileAttachmentLocal fileAttachmentLocal = FileAttachmentUtil.getLocalHome().findByPrimaryKey(p_fileAttachmentPK);
                return FileAttachmentSessionUtil.getLocalHome().create().fileAttachmentInputStream(fileAttachmentLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
        catch(FileNotFoundException e) {
            throw new EJBException(e);
        }
        catch(IOException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get an XML string describing the report generated for the given person and
     * node and date range.
     *
     * @param p_key User's security key
     * @param p_task Task that the times are required for
     * @param p_contactablePKs The contactables whose times are required
     * @param p_recursive Should the sub-tree be searched?
     * @param p_start Start date for time
     * @param p_stop Stop date for time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String getNodeSearchTimeLogXML(com.velocityme.interfaces.KeySession p_key,
                                                    com.velocityme.interfaces.NodePK p_nodePK,
                                                    com.velocityme.interfaces.ContactablePK[] p_contactablePKs,
                                                    boolean p_recursive,
                                                    boolean p_taskSummary,
                                                    boolean p_typeSummary,
                                                    boolean p_stateSummary,
                                                    boolean p_entries,
                                                    Date p_start,
                                                    Date p_stop)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            ContactableLocal[] contactableLocals = new ContactableLocal[p_contactablePKs.length];
            for (int i = 0; i < p_contactablePKs.length; i++)
                contactableLocals[i] = ContactableUtil.getLocalHome().findByPrimaryKey(p_contactablePKs[i]);
            return NodeSessionUtil.getLocalHome().create().searchTimeLogXML(keyLocal, nodeLocal, contactableLocals, p_recursive, p_taskSummary, p_typeSummary, p_stateSummary, p_entries, p_start, p_stop);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get TimeEntry[] for details for the specified time search
     *
     * @param p_key User's security key
     * @param p_nodePK Node that the times are required for
     * @param p_contactablePKs The contactables whose times are required
     * @param p_recursive Should the sub-tree be searched?
     * @param p_start Start date for time
     * @param p_stop Stop date for time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getNodeSearchTimeLogValue(com.velocityme.interfaces.KeySession p_key,
                                                   com.velocityme.interfaces.NodePK p_nodePK,
                                                   com.velocityme.interfaces.ContactablePK[] p_contactablePKs,
                                                   boolean p_recursive,
                                                   boolean p_taskSummary,
                                                   boolean p_typeSummary,
                                                   boolean p_stateSummary,
                                                   boolean p_monthSummary,
                                                   boolean p_weekSummary,
                                                   boolean p_daySummary,
                                                   boolean p_entries,
                                                   Date p_start,
                                                   Date p_stop)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            ContactableLocal[] contactableLocals = new ContactableLocal[p_contactablePKs.length];
            for (int i = 0; i < p_contactablePKs.length; i++)
                contactableLocals[i] = ContactableUtil.getLocalHome().findByPrimaryKey(p_contactablePKs[i]);
            return NodeSessionUtil.getLocalHome().create().searchTimeLogValue(keyLocal, nodeLocal, contactableLocals, p_recursive, p_taskSummary, p_typeSummary, p_stateSummary, p_monthSummary, p_weekSummary, p_daySummary, p_entries, p_start, p_stop);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get TimeEntry[] for details for the specified time search
     *
     * @param p_key User's security key
     * @param p_sprintPK Sprint that the times are required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getSprintSearchTimeLogValue(com.velocityme.interfaces.KeySession p_key,
                                                     com.velocityme.interfaces.SprintPK p_sprintPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SprintLocal sprintLocal = SprintUtil.getLocalHome().findByPrimaryKey(p_sprintPK);
            ContactableLocal[] contactableLocals = new ContactableLocal[sprintLocal.getTeamPersonsLocal().size()];
            int i = 0;
            Iterator it = sprintLocal.getTeamPersonsLocal().iterator();
            while (it.hasNext()) {
                PersonLocal personLocal = (PersonLocal)it.next();
                contactableLocals[i++] = personLocal.getContactableLocal();
            }
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findRoot();
            return NodeSessionUtil.getLocalHome().create().searchTimeLogValue(keyLocal, nodeLocal, contactableLocals, 
                    true, false, false, false, false, false, true, false, sprintLocal.getStartDate(), sprintLocal.getStopDate());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get TimeEntry[] for details for the specified time search which excludes the sprint
     * linked nodes.
     *
     * @param p_key User's security key
     * @param p_sprintPK Sprint that the times are required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getSprintUnplannedSearchTimeLogValue(com.velocityme.interfaces.KeySession p_key,
                                                              com.velocityme.interfaces.SprintPK p_sprintPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SprintLocal sprintLocal = SprintUtil.getLocalHome().findByPrimaryKey(p_sprintPK);
            ContactableLocal[] contactableLocals = new ContactableLocal[sprintLocal.getTeamPersonsLocal().size()];
            int i = 0;
            Iterator it = sprintLocal.getTeamPersonsLocal().iterator();
            while (it.hasNext()) {
                PersonLocal personLocal = (PersonLocal)it.next();
                contactableLocals[i++] = personLocal.getContactableLocal();
            }
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findRoot();
            return NodeSessionUtil.getLocalHome().create().searchTimeLogFilteredValue(keyLocal, nodeLocal, 
                    sprintLocal.getNodeLocal().getAllLinkedNodesLocal(), contactableLocals, true, true, 
                    false, false, false, false, false, false, sprintLocal.getStartDate(), sprintLocal.getStopDate());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get duration sums for a tree of tasks between the specified start and stop dates
     *
     * @param p_key User's security key
     * @param p_nodePK Node that the times are required for
     * @param p_recursive indicates whether just the node or branch should be searched
     * @param p_start Start date for time
     * @param p_stop Stop date for time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getNodeDurationSum(com.velocityme.interfaces.KeySession p_key,
                                         	com.velocityme.interfaces.NodePK p_nodePK,
                                            boolean p_recursive,
                                            Date p_start,
                                            Date p_stop)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return NodeSessionUtil.getLocalHome().create().searchDurationSum(keyLocal, nodeLocal, true, p_recursive, p_start, p_stop, false);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full path name for the node.
     *
     * @param p_key User's security key
     * @param p_nodePK Node that the path name is required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String getNodePathName(com.velocityme.interfaces.KeySession p_key,
                                            com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return nodeLocal.getPathName();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the path name up to the containing Project for the task.
     *
     * @param p_key User's security key
     * @param p_taskPK Task that the path name is required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String getProjectPathName(com.velocityme.interfaces.KeySession p_key,
                                               com.velocityme.interfaces.TaskPK p_taskPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            return taskLocal.getProjectPathName();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Find a system node given it's name.
     *
     * @param p_key User's security key
     * @param p_name The name of a node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.NodePK findSystemNodeByName(com.velocityme.interfaces.KeySession p_key,
                                                                 java.lang.String p_name)
        throws InvalidKeyException {
        try {
            if (p_key.isValid()) {
                NodeLocal nodeLocal = NodeUtil.getLocalHome().findSystemNodeByName(p_name);
                return new NodePK(nodeLocal.getNodeId());
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Find the root node.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.NodePK findNodeRoot(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            if (p_key.isValid()) {
                NodeLocal nodeLocal = NodeUtil.getLocalHome().findRoot();
                return new NodePK(nodeLocal.getNodeId());
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Find the directory node.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.NodePK findDirectoryNode(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            if (p_key.isValid()) {
                NodeLocal nodeLocal = NodeUtil.getLocalHome().findDirectoryNode();
                return new NodePK(nodeLocal.getNodeId());
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Organisation in the specified 
     * parentnode then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNodePK The node which will contain the new Organisation
     * @param p_organisationValue The value details for the Organisation part of the organisation
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.OrganisationPK organisationCreate(KeySession p_key,
                                                                       NodePK p_parentNodePK,
                                                                       com.velocityme.valueobjects.OrganisationValue p_organisationValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            OrganisationLocal organisationLocal = OrganisationSessionUtil.getLocalHome().create().createOrganisation(keyLocal, parentNodeLocal, p_organisationValue);
            return new OrganisationPK(organisationLocal.getOrganisationId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the organisation then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_organisationPK The Organisation object being edited
     * @param p_organisationValue The value details for the Organisation part of the organisation
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void organisationEdit(KeySession p_key,
                                 OrganisationPK p_organisationPK,
                                 com.velocityme.valueobjects.OrganisationValue p_organisationValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            OrganisationLocal organisationLocal = OrganisationUtil.getLocalHome().findByPrimaryKey(p_organisationPK);
            OrganisationSessionUtil.getLocalHome().create().editOrganisation(keyLocal, organisationLocal, p_organisationValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of organisation value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllOrganisationValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return OrganisationSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the organisation value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_organisationPK The Action primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.OrganisationValue getOrganisationValue(KeySession p_key,
                                                                              OrganisationPK p_organisationPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            OrganisationLocal organisationLocal = OrganisationSessionUtil.getLocalHome().create().getOrganisationLocal(getKeyLocal(p_key), p_organisationPK);
            OrganisationValue organisationValue = organisationLocal.getOrganisationValue();
            ContactableValueToString.sortContactDetails(organisationValue.getContactableValue());
            return organisationValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of permission value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Set getAllPermissionValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return PermissionSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Add a new licence key. Note that you don't have to be logged in to perform
     * this action!
     *
     * @param p_encodedLicence an encoded licence key
     * @return true to indicate success, false indicates the licence already exists
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean addEncodedLicence(String p_encodedLicence) {
        try {
            return LicenceKeySessionUtil.getLocalHome().create().addEncodedLicence(p_encodedLicence);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of installed licence keys.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.utility.LicenceKey[] getAllLicenceKeys() throws InvalidKeyException {
        try {
            return LicenceKeySessionUtil.getLocalHome().create().getAllLicenceKeys();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Sprint in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Person
     * @param p_sprintValue The value details for the Sprint part of the sprint
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.SprintPK sprintCreate(KeySession p_key,
                                                           NodePK p_parentNodePK,
                                                           com.velocityme.valueobjects.SprintValue p_sprintValue,
                                                           Collection p_personsPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            Collection personsLocal = new ArrayList();
            Iterator i = p_personsPK.iterator();
            while(i.hasNext()) {
                personsLocal.add(PersonUtil.getLocalHome().findByPrimaryKey((PersonPK)i.next()));
            }
            SprintLocal sprintLocal = SprintSessionUtil.getLocalHome().create().createSprint(keyLocal, parentNodeLocal, p_sprintValue, personsLocal);
            return new SprintPK(sprintLocal.getSprintId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the sprint then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_sprint The Sprint object being edited
     * @param p_sprintValue The value details for the Sprint part of the sprint
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void sprintEdit(KeySession p_key,
                           SprintPK p_sprintPK,
                           com.velocityme.valueobjects.SprintValue p_sprintValue,
                           Collection p_personsPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SprintLocal sprintLocal = SprintUtil.getLocalHome().findByPrimaryKey(p_sprintPK);
            Collection personsLocal = new ArrayList();
            Iterator i = p_personsPK.iterator();
            while(i.hasNext()) {
                personsLocal.add(PersonUtil.getLocalHome().findByPrimaryKey((PersonPK)i.next()));
            }
            SprintSessionUtil.getLocalHome().create().editSprint(keyLocal, sprintLocal, p_sprintValue, personsLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the sprint value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_sprintPK The Sprint primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.SprintValue getSprintValue(KeySession p_key,
                                                                  SprintPK p_sprintPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            SprintLocal sprintLocal = SprintSessionUtil.getLocalHome().create().getSprintLocal(getKeyLocal(p_key), p_sprintPK);
            SprintValue sprintValue = sprintLocal.getSprintValue();
            return sprintValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the sprint team person value objects corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_sprintPK The Sprint primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public Collection getSprintTeamPersonValues(KeySession p_key,
                                                SprintPK p_sprintPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            SprintLocal sprintLocal = SprintSessionUtil.getLocalHome().create().getSprintLocal(getKeyLocal(p_key), p_sprintPK);
            Collection teamPersonsLocal = sprintLocal.getTeamPersonsLocal();
            Collection teamPersonsValue = new ArrayList();
            Iterator i = teamPersonsLocal.iterator();
            while (i.hasNext()) {
                PersonLocal personLocal = (PersonLocal)i.next();
                PersonValue personValue = personLocal.getPersonValue();
                teamPersonsValue.add(personValue);
            }
            return teamPersonsValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get duration sums for a sprint
     *
     * @param p_key User's security key
     * @param p_nodePK Node that the times are required for
     * @param p_recursive indicates whether just the node or branch should be searched
     * @param p_start Start date for time
     * @param p_stop Stop date for time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getSprintDurationSum(com.velocityme.interfaces.KeySession p_key,
                                              com.velocityme.interfaces.SprintPK p_sprintPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SprintLocal sprintLocal = SprintUtil.getLocalHome().findByPrimaryKey(p_sprintPK);
            return SprintSessionUtil.getLocalHome().create().searchDurationSum(keyLocal, sprintLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get progress sums for a sprint
     *
     * @param p_key User's security key
     * @param p_sprintPK Sprint that the sums are required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Map getSprintProgressSum(com.velocityme.interfaces.KeySession p_key,
                                              com.velocityme.interfaces.SprintPK p_sprintPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            SprintLocal sprintLocal = SprintUtil.getLocalHome().findByPrimaryKey(p_sprintPK);
            return SprintSessionUtil.getLocalHome().create().searchProgressSum(keyLocal, sprintLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Person in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Person
     * @param p_personValue The value details for the Person part of the person
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.PersonPK personCreate(KeySession p_key,
                                                           NodePK p_parentNodePK,
                                                           com.velocityme.valueobjects.PersonValue p_personValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            PersonLocal personLocal = PersonSessionUtil.getLocalHome().create().createPerson(keyLocal, parentNodeLocal, p_personValue);
            return new PersonPK(personLocal.getPersonId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the person then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_person The Person object being editted
     * @param p_personValue The value details for the Person part of the person
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void personEdit(KeySession p_key,
                           PersonPK p_personPK,
                           com.velocityme.valueobjects.PersonValue p_personValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            PersonLocal personLocal = PersonUtil.getLocalHome().findByPrimaryKey(p_personPK);
            PersonSessionUtil.getLocalHome().create().editPerson(keyLocal, personLocal, p_personValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the person value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_personPK The Person primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.PersonValue getPersonValue(KeySession p_key,
                                                                  PersonPK p_personPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            PersonLocal personLocal = PersonSessionUtil.getLocalHome().create().getPersonLocal(getKeyLocal(p_key), p_personPK);
            PersonValue personValue = personLocal.getPersonValue();
            ContactableValueToString.sortContactDetails(personValue.getContactableValue());
            return personValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of person value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllPersonValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return PersonSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the list of user value objects for a particular person.
     *
     * @param p_key User's security key
     * @param p_person Person whose users are required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getPersonUserValues(KeySession p_key, 
                                                    PersonPK p_personPK) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            PersonLocal personLocal = PersonUtil.getLocalHome().findByPrimaryKey(p_personPK);
            return PersonSessionUtil.getLocalHome().create().getUserValueObjects(keyLocal, personLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the list of time value objects for a particular person in the date range.
     *
     * @param p_key User's security key
     * @param p_person Person whose users are required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getPersonTimeValues(KeySession p_key, 
                                                    PersonPK p_personPK,
                                                    Date p_start,
                                                    Date p_stop) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            PersonLocal personLocal = PersonUtil.getLocalHome().findByPrimaryKey(p_personPK);
            return PersonSessionUtil.getLocalHome().create().getTimeValues(keyLocal, personLocal, p_start, p_stop);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned to the specified person.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="both"
     **/
    public com.velocityme.valueobjects.TaskValue[] getPersonTaskValues(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            Set taskLocals = new TreeSet(new Comparator() {
                public int compare(Object o1, Object o2) {
                    TaskLocal n1 = (TaskLocal)o1;
                    TaskLocal n2 = (TaskLocal)o2;
                    return (n1.getProjectPathName()+n1.getNodeLocal().getName()).compareTo(n2.getProjectPathName()+n2.getNodeLocal().getName());
                }
            });
            taskLocals.addAll(SearchSessionUtil.getLocalHome().create().findAllMyResponsibleTaskLocals(keyLocal));
            Iterator it = p_key.getLocal().getUserLocal().getBookmarkNodesLocal().iterator();
            while (it.hasNext()) {
                NodeLocal nodeLocal = (NodeLocal)it.next();
                if (nodeLocal.getTaskLocal() != null)
                    taskLocals.add(nodeLocal.getTaskLocal());
            }
            TaskValue[] taskValues = new TaskValue[taskLocals.size()];
            it = taskLocals.iterator();
            int i = 0;
            while (it.hasNext()) {
                TaskLocal taskLocal = (TaskLocal)it.next();
                TaskValue taskValue = taskLocal.getTaskValue();
                taskValues[i++] = taskValue;
            }
            return taskValues;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Project in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Project
     * @param p_projectValue The value details for the Project part of the person
     *
     * @ejb.interface-method view-type="remote"
     */
    public com.velocityme.interfaces.ProjectPK projectCreate(KeySession p_key,
                                                             NodePK p_parentNodePK,
                                                             com.velocityme.valueobjects.ProjectValue p_projectValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            ProjectLocal projectLocal = ProjectSessionUtil.getLocalHome().create().createProject(keyLocal, parentNodeLocal, p_projectValue);
            return new ProjectPK(projectLocal.getProjectId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the project then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_projectPK The Project object being editted
     * @param p_projectValue The value details for the Project part of the project
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void projectEdit(KeySession p_key,
                            ProjectPK p_projectPK,
                            com.velocityme.valueobjects.ProjectValue p_projectValue,
                            com.velocityme.interfaces.ContactablePK[] p_responsibleContactablePKs,
                            com.velocityme.interfaces.ContactablePK[] p_interestedContactablePKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            ProjectLocal projectLocal = ProjectUtil.getLocalHome().findByPrimaryKey(p_projectPK);
            Collection responsibleContactableLocals = new ArrayList();
            for (int i = 0; i < p_responsibleContactablePKs.length; i++)
                responsibleContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_responsibleContactablePKs[i]));
            Collection interestedContactableLocals = new ArrayList();
            for (int i = 0; i < p_interestedContactablePKs.length; i++)
                interestedContactableLocals.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_interestedContactablePKs[i]));
            ProjectSessionUtil.getLocalHome().create().editProject(keyLocal, projectLocal, p_projectValue, responsibleContactableLocals, interestedContactableLocals);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the project value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_projectPK The Project primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.ProjectValue getProjectValue(KeySession p_key,
                                                                    ProjectPK p_projectPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            ProjectLocal projectLocal = ProjectSessionUtil.getLocalHome().create().getProjectLocal(getKeyLocal(p_key), p_projectPK);
            return projectLocal.getProjectValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Role in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Role
     * @param p_roleValue The value details for the Role part of the role
     * @param p_permissions The set of permissions assigned to the role (PKs)
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.RolePK roleCreate(KeySession p_key,
                                                       NodePK p_parentNodePK,
                                                       com.velocityme.valueobjects.RoleValue p_roleValue,
                                                       java.util.Set p_permissionPKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            Set permissionLocals = new HashSet();
            Iterator i = p_permissionPKs.iterator();
            while(i.hasNext()) {
                permissionLocals.add(PermissionUtil.getLocalHome().findByPrimaryKey((PermissionPK)i.next()));
            }
            RoleLocal roleLocal = RoleSessionUtil.getLocalHome().create().createRole(keyLocal, parentNodeLocal, p_roleValue, permissionLocals);
            return new RolePK(roleLocal.getRoleId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the Role then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_role The Role object being editted
     * @param p_roleValue The value details for the Role part of the role
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void roleEdit(KeySession p_key,
                         RolePK p_rolePK,
                         com.velocityme.valueobjects.RoleValue p_roleValue,
                         java.util.Set p_permissionPKs)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            RoleLocal roleLocal = RoleUtil.getLocalHome().findByPrimaryKey(p_rolePK);
            Set permissionLocals = new HashSet();
            Iterator i = p_permissionPKs.iterator();
            while(i.hasNext()) {
                permissionLocals.add(PermissionUtil.getLocalHome().findByPrimaryKey((PermissionPK)i.next()));
            }
            RoleSessionUtil.getLocalHome().create().editRole(keyLocal, roleLocal, p_roleValue, permissionLocals);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the role value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_rolePK The Role primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.RoleValue getRoleValue(KeySession p_key,
                                                              RolePK p_rolePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            RoleLocal roleLocal = RoleSessionUtil.getLocalHome().create().getRoleLocal(getKeyLocal(p_key), p_rolePK);
            return roleLocal.getRoleValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of role value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.RoleValue[] getAllRoleValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return RoleSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the the list of permissions assigned to a particular role.
     *
     * @param p_key User's security key
     * @param p_rolePK Role
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Set getRoleAssignedPermissionValues(KeySession p_key,
                                                         RolePK p_rolePK) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            RoleLocal roleLocal = RoleUtil.getLocalHome().findByPrimaryKey(p_rolePK);
            return RoleSessionUtil.getLocalHome().create().getAssignedPermissionValues(keyLocal, roleLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned to the specified person.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findAllMyResponsibleTasks(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findAllMyResponsibleTaskLocals(keyLocal);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, "");
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned to the specified person below
     * the specified node.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findMyResponsibleTasks(com.velocityme.interfaces.KeySession p_key, 
                                                       com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findMyResponsibleTaskLocals(keyLocal, nodeLocal);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned any of the specified contactables.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     * @param p_contactablePks Array of contactables to search for
     * @param p_includeDescendents Should the descendent contactables be included
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findContactablesResponsibleTasks(com.velocityme.interfaces.KeySession p_key, 
                                                                 com.velocityme.interfaces.NodePK p_nodePK,
                                                                 com.velocityme.interfaces.ContactablePK[] p_contactablePks,
                                                                 boolean p_includeDescendents)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection contactablesLocal = new ArrayList();
            for (int i = 0; i < p_contactablePks.length; i++) {
                contactablesLocal.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_contactablePks[i]));
            }
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findContactablesResponsibleTaskLocals(keyLocal, nodeLocal, contactablesLocal, p_includeDescendents);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned to the specified person.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findAllMyInterestedTasks(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findAllMyInterestedTaskLocals(keyLocal);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, "");
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks assigned to the specified person below
     * the specified node.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findMyInterestedTasks(com.velocityme.interfaces.KeySession p_key, 
                                                      com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findMyInterestedTaskLocals(keyLocal, nodeLocal);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks that are not in the start state.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findActiveTasks(com.velocityme.interfaces.KeySession p_key, 
                                                com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findActiveTaskLocals(keyLocal, nodeLocal);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks created since the specified date in
     * the specified node.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     * @param p_startDate The start date for new tasks
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findNewTasks(com.velocityme.interfaces.KeySession p_key, 
                                             com.velocityme.interfaces.NodePK p_nodePK,
                                             java.util.Date p_startDate)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return SearchSessionUtil.getLocalHome().create().findParameterSearch(keyLocal, nodeLocal, new Integer[0], new String[0], p_startDate, null, new StatusPK[0], new ContactablePK[0]);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks completed since the specified date in
     * the specified node.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     * @param p_startDate The start date for completed tasks
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findCompletedTasks(com.velocityme.interfaces.KeySession p_key, 
                                                   com.velocityme.interfaces.NodePK p_nodePK,
                                                   java.util.Date p_startDate)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findCompletedTaskLocals(keyLocal, nodeLocal, p_startDate);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks changed between the specified dates in
     * the specified node.
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     * @param p_startDate The start date for changed tasks
     * @param p_stopDate The stop date for changed tasks
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findChangedTasks(com.velocityme.interfaces.KeySession p_key, 
                                                 com.velocityme.interfaces.NodePK p_nodePK,
                                                 java.util.Date p_startDate,
                                                 java.util.Date p_stopDate)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Collection taskLocals = SearchSessionUtil.getLocalHome().create().findChangedTaskLocals(keyLocal, nodeLocal, p_startDate, p_stopDate);
            return SearchSessionUtil.getLocalHome().create().convertTasksToResults(taskLocals, nodeLocal.getPathName());
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Search the node tree for the tasks which meet the specified search parameters
     *
     * @param p_key User's security key
     * @param p_nodePK The node which is the root of the search
     *
     * @ejb.interface-method view-type="both"
     **/
    public java.util.Collection findParameterSearch(com.velocityme.interfaces.KeySession p_key,
                                                    com.velocityme.interfaces.NodePK p_nodePK,
                                                    java.lang.Integer[] p_ids, 
                                                    java.lang.String[] p_keywords,
                                                    java.util.Date p_start,
                                                    java.util.Date p_stop,
                                                    com.velocityme.interfaces.StatusPK[] p_statusPks,
                                                    com.velocityme.interfaces.ContactablePK[] p_contactablePks)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return SearchSessionUtil.getLocalHome().create().findParameterSearch(keyLocal, nodeLocal, p_ids, p_keywords, p_start, p_stop, p_statusPks, p_contactablePks);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }        
    }
    
    /**
     * Get an XML string describing the report for the collection of nodes that are
     * provided.
     *
     * @param p_key User's security key
     * @param p_results Collection of NodeResults that the report is required for
     * @param p_bStateChanges Should state changes be included in the report?
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.lang.String searchReportXML(com.velocityme.interfaces.KeySession p_key,
                                            com.velocityme.interfaces.NodePK p_rootNodePK,
                                            java.util.Collection p_nodeSearchResults,
                                            boolean p_bStateChanges,
                                            boolean p_bComments) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal rootNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_rootNodePK);
            return SearchSessionUtil.getLocalHome().create().searchReportXML(keyLocal, rootNodeLocal, p_nodeSearchResults, p_bStateChanges, p_bComments);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get value objects describing the report for the collection of nodes that are
     * provided.
     *
     * @param p_key User's security key
     * @param p_results Collection of NodeResults that the report is required for
     * @param p_bStateChanges Should state changes be included in the report?
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection searchReportValue(com.velocityme.interfaces.KeySession p_key,
                                                  com.velocityme.interfaces.NodePK p_rootNodePK,
                                                  java.util.Collection p_nodeSearchResults,
                                                  boolean p_bStateChanges,
                                                  boolean p_bComments,
                                                  boolean p_bResponsibility) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal rootNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_rootNodePK);
            return SearchSessionUtil.getLocalHome().create().searchReportValue(keyLocal, rootNodeLocal, p_nodeSearchResults, p_bStateChanges, p_bComments, p_bResponsibility);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get a set of all permissions that are currently assigned to the user in the
     * specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Set getAssignedPermissions(com.velocityme.interfaces.KeySession p_key,
                                                com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = null;
            if (p_nodePK != null)
                nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            Set permissionsLocal = SearchSessionUtil.getLocalHome().create().getAssignedPermissionsLocal(keyLocal, nodeLocal);
            Set permissionPKs = new HashSet();
            Iterator i = permissionsLocal.iterator();
            while(i.hasNext()) {
                permissionPKs.add(((PermissionLocal)i.next()).getPrimaryKey());
            }
            return permissionPKs;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new State in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new State
     * @param p_stateValue The value details for the State part of the state
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.StatePK stateCreate(KeySession p_key,
                                                         NodePK p_parentNodePK,
                                                         com.velocityme.valueobjects.StateValue p_stateValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            StateLocal stateLocal = StateSessionUtil.getLocalHome().create().createState(keyLocal, parentNodeLocal, p_stateValue);
            return new StatePK(stateLocal.getStateId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the State then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_statePK The State object being editted
     * @param p_stateValue The value details for the State part of the state
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void stateEdit(KeySession p_key,
                          StatePK p_statePK,
                          com.velocityme.valueobjects.StateValue p_stateValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            StateLocal stateLocal = StateUtil.getLocalHome().findByPrimaryKey(p_statePK);
            StateSessionUtil.getLocalHome().create().editState(keyLocal, stateLocal, p_stateValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the start state value object.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StateValue getStartStateValue(com.velocityme.interfaces.KeySession p_key)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return StateSessionUtil.getLocalHome().create().getStartStateValueObject(keyLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the state value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_statePK The State primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StateValue getStateValue(KeySession p_key,
                                                                StatePK p_statePK) {
        try {
            StateLocal stateLocal = StateUtil.getLocalHome().findByPrimaryKey(p_statePK);
            return stateLocal.getStateValue();
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of status value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StateValue[] getAllStateValues(com.velocityme.interfaces.KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return StateSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Status in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Statue
     * @param p_statusValue The value details for the Statue part of the status
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.StatusPK statusCreate(KeySession p_key,
                                                           NodePK p_parentNodePK,
                                                           com.velocityme.valueobjects.StatusValue p_statusValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            StatusLocal statusLocal = StatusSessionUtil.getLocalHome().create().createStatus(keyLocal, parentNodeLocal, p_statusValue);
            return new StatusPK(statusLocal.getStatusId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the Status then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_status The Status object being editted
     * @param p_statusValue The value details for the Status part of the status
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void statusEdit(KeySession p_key,
                           StatusPK p_statusPK,
                           com.velocityme.valueobjects.StatusValue p_statusValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            StatusLocal statusLocal = StatusUtil.getLocalHome().findByPrimaryKey(p_statusPK);
            StatusSessionUtil.getLocalHome().create().editStatus(keyLocal, statusLocal, p_statusValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the status value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_statusPK The State primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StatusValue getStatusValue(KeySession p_key,
                                                                  StatusPK p_statusPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            StatusLocal statusLocal = StatusSessionUtil.getLocalHome().create().getStatusLocal(getKeyLocal(p_key), p_statusPK);
            return statusLocal.getStatusValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of status value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.StatusValue[] getAllStatusValues(com.velocityme.interfaces.KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return StatusSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to change state on a specified task then go 
     * ahead and change it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_taskPK The task which is changing state
     * @param p_transitionValue The value details for the state transition
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskChangeState(com.velocityme.interfaces.KeySession p_key,
                                com.velocityme.interfaces.TaskPK p_taskPK,
                                com.velocityme.interfaces.TransitionPK p_transitionPK,
                                java.lang.String p_description,
                                java.lang.Byte p_percentageComplete,
                                java.io.File p_file,
                                java.lang.String p_contentType,
                                java.io.InputStream p_stream)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            TransitionLocal transitionLocal = TransitionUtil.getLocalHome().findByPrimaryKey(p_transitionPK);
            TaskSessionUtil.getLocalHome().create().changeState(keyLocal, taskLocal, transitionLocal, p_description, p_percentageComplete, p_file, p_contentType, p_stream);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to reassign responsibility on a specified task 
     * then go ahead and change it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_taskPK The task which is changing state
     * @param p_transitionValue The value details for the state transition
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskReassignResponsibility(com.velocityme.interfaces.KeySession p_key,
                                           com.velocityme.interfaces.TaskPK p_taskPK,
                                           com.velocityme.interfaces.ContactablePK[] p_contactablesPK,
                                           java.lang.String p_description,
                                           java.io.File p_file,
                                           java.lang.String p_contentType,
                                           java.io.InputStream p_stream)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            Collection contactablesLocal = new ArrayList();
            for (int i = 0; i < p_contactablesPK.length; i++) {
                contactablesLocal.add(ContactableUtil.getLocalHome().findByPrimaryKey(p_contactablesPK[i]));
            }
            TaskSessionUtil.getLocalHome().create().reassignResponsibility(keyLocal, taskLocal, contactablesLocal, p_description, p_file, p_contentType, p_stream);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to assign time on a specified task then go 
     * ahead.
     *
     * @param p_key User's security key
     * @param p_task The task
     * @param p_timeValue The value details for the time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskTimeAssign(KeySession p_key,
                               TaskPK p_taskPK,
                               Byte p_percentageComplete,
                               com.velocityme.valueobjects.TimeValue p_timeValue)
        throws PermissionDeniedException, InvalidKeyException, InvalidTimeException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            TaskSessionUtil.getLocalHome().create().assignTime(keyLocal, taskLocal, p_percentageComplete, p_timeValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to add time on a specified task then go 
     * ahead.
     *
     * @param p_key User's security key
     * @param p_task The task
     * @param p_hours The number of hours to add
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskTimeQuickAdd(KeySession p_key,
                                 TaskPK p_taskPK,
                                 int p_hours)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            TaskSessionUtil.getLocalHome().create().quickAddTime(keyLocal, taskLocal, p_hours);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit time on a specified task then go 
     * ahead.
     *
     * @param p_key User's security key
     * @param p_timeValue The value details for the time
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskTimeEdit(KeySession p_key,
                             Byte p_percentageComplete,
                             com.velocityme.valueobjects.TimeValue p_timeValue)
        throws PermissionDeniedException, InvalidKeyException, InvalidTimeException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TimeLocal timeLocal = TimeUtil.getLocalHome().findByPrimaryKey(p_timeValue.getPrimaryKey());
            TaskSessionUtil.getLocalHome().create().editTime(keyLocal, timeLocal, p_percentageComplete, p_timeValue);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit time on a specified task then go 
     * ahead and delete it.
     *
     * @param p_key User's security key
     * @param p_timeValue The value details for the time to delete
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskTimeDelete(KeySession p_key,
                               com.velocityme.interfaces.TimePK p_timePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TimeLocal timeLocal = TimeUtil.getLocalHome().findByPrimaryKey(p_timePK);
            TaskSessionUtil.getLocalHome().create().deleteTime(keyLocal, timeLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the time value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_timePK The Time primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.TimeValue getTimeValue(KeySession p_key,
                                                              TimePK p_timePK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid())
                return TimeUtil.getLocalHome().findByPrimaryKey(p_timePK).getTimeValue();
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of time value objects for the given task.
     *
     * @param p_key User's security key
     * @param p_task Task that the times are required for
     * @param p_date Start date from which to find entries
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getTaskTimeValues(KeySession p_key,
                                                  TaskPK p_taskPK,
                                                  Date p_date) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            return TaskSessionUtil.getLocalHome().create().getTimesValue(keyLocal, taskLocal, p_date);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the current list of legal transition value objects for the given task.
     *
     * @param p_key User's security key
     * @param p_taskPK Task that the transitions are required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getTaskLegalTransitionValues(KeySession p_key, TaskPK p_taskPK) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                KeySessionLocal keyLocal = getKeyLocal(p_key);
                TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
                Collection transitionLocals = TaskSessionUtil.getLocalHome().create().getLegalTransitionLocals(keyLocal, taskLocal);
                Iterator i = transitionLocals.iterator();
                Collection transitionValues = new ArrayList();
                while(i.hasNext()) {
                    TransitionLocal transitionLocal = (TransitionLocal)i.next();
                    transitionValues.add(new TransitionValueToString(transitionLocal.getTransitionValue()));
                }
                return transitionValues;
            }
            else
                throw new InvalidKeyException();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the time of the last state change for the specified task
     *
     * @param p_key User's security key
     * @param p_taskPK Task that the time is required for
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Date getTaskLastStateChangeTime(KeySession p_key, TaskPK p_taskPK) 
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                KeySessionLocal keyLocal = getKeyLocal(p_key);
                TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
                return TaskSessionUtil.getLocalHome().create().getTaskLastStateChangeTime(keyLocal, taskLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Recursively walk the tree updating first the children then the current task
     *
     * @param p_key User's security key
     * @param p_task Task that is the root of the update
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskRecursiveUpdateTimes(KeySession p_key, TaskPK p_taskPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                KeySessionLocal keyLocal = getKeyLocal(p_key);
                TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
                TaskSessionUtil.getLocalHome().create().recursiveUpdateTimes(keyLocal, taskLocal);
            }
            else
                throw new InvalidKeyException();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new TaskStateMachine in the 
     * specified parentnode then go ahead and create it and log an appropriate 
     * ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new TaskStateMachine
     * @param p_taskStateMachineValue The value details for the TasktateMachine part of the TaskStateMachine
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.TaskStateMachinePK taskStateMachineCreate(com.velocityme.interfaces.KeySession p_key,
                                                                               com.velocityme.interfaces.NodePK p_parentNodePK,
                                                                               com.velocityme.valueobjects.TaskStateMachineValue p_taskStateMachineValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            TaskStateMachineLocal taskStateMachineLocal = TaskStateMachineSessionUtil.getLocalHome().create().createTaskStateMachine(keyLocal, parentNodeLocal, p_taskStateMachineValue);
            return new TaskStateMachinePK(taskStateMachineLocal.getTaskStateMachineId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the task state machine then do so and 
     * log the changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_project The Project object being edited
     * @param p_taskStateMachineValue The value details for the TaskStateMachine part of the TaskStateMachine
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskStateMachineEdit(com.velocityme.interfaces.KeySession p_key,
                                     com.velocityme.interfaces.TaskStateMachinePK p_taskStateMachinePK,
                                     com.velocityme.valueobjects.TaskStateMachineValue p_taskStateMachineValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskStateMachineLocal taskStateMachineLocal = TaskStateMachineUtil.getLocalHome().findByPrimaryKey(p_taskStateMachinePK);
            TaskStateMachineSessionUtil.getLocalHome().create().editTaskStateMachine(keyLocal, taskStateMachineLocal, p_taskStateMachineValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the task state machine value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_taskStateMachinePK The Task State Machine primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.TaskStateMachineValue getTaskStateMachineValue(KeySession p_key,
                                                                                      TaskStateMachinePK p_taskStateMachinePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            TaskStateMachineLocal taskStateMachineLocal = TaskStateMachineSessionUtil.getLocalHome().create().getTaskStateMachineLocal(getKeyLocal(p_key), p_taskStateMachinePK);
            return taskStateMachineLocal.getTaskStateMachineValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of task state machine value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllTaskStateMachineValues(com.velocityme.interfaces.KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return TaskStateMachineSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of children nodes that can be seen by this user from the 
     * specified node. If p_node == null then the method returns all nodes 
     * where the user is allocated to roles. This option should be called first 
     * by the client to create the base of the user's tree.
     *
     * @param p_key User's security key
     * @param p_node Current node in which the children will be found
     * @return A collection of nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleChildrenValues(KeySession p_key,
                                                         NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = null;
            if (p_nodePK != null)
                nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TreeSessionUtil.getLocalHome().create().getVisibleChildrenValue(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of ancestor nodes that can be seen by this user from the 
     * specified node. If p_node == null then the method returns an empty collection
     *
     * @param p_key User's security key
     * @param p_node Current node in which the children will be found
     * @return A collection of ancestor nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleAncestorValues(KeySession p_key,
                                                         NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = null;
            if (p_nodePK != null)
                nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TreeSessionUtil.getLocalHome().create().getVisibleAncestorValue(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of sibling nodes that can be seen by this user from the 
     * specified node. If p_node == null then the method returns null.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the siblings will be found
     * @return A collection of sibling nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleSiblingValues(KeySession p_key,
                                                        NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = null;
            if (p_nodePK != null)
                nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TreeSessionUtil.getLocalHome().create().getVisibleSiblingsValue(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of linked nodes that can be seen by this user from the 
     * specified node. If p_node == null then the method returns null.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of linked nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleLinkedValues(KeySession p_key,
                                                       NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = null;
            if (p_nodePK != null)
                nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TreeSessionUtil.getLocalHome().create().getVisibleLinkedValue(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of dependency tasks that can be seen by this user from the 
     * specified task. If p_node == null then the method returns null.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of linked nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleDependencyTaskValues(KeySession p_key,
                                                               NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = null;
            if (p_nodePK != null) {
                NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
                taskLocal = nodeLocal.getTaskLocal();
            }
            return TreeSessionUtil.getLocalHome().create().getVisibleDependencyTaskValues(keyLocal, taskLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of dependant tasks that can be seen by this user from the 
     * specified task. If p_node == null then the method returns null.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of linked nodes that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getVisibleDependantTaskValues(KeySession p_key,
                                                              NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = null;
            if (p_nodePK != null) {
                NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
                taskLocal = nodeLocal.getTaskLocal();
            }
            return TreeSessionUtil.getLocalHome().create().getVisibleDependantTaskValues(keyLocal, taskLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of bookmarked nodes for the current user
     * 
     * @param p_key User's security key
     * @return A collection of bookmarked nodes for the current user
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getBookmarkNodeValues(KeySession p_key) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return TreeSessionUtil.getLocalHome().create().getBookmarkNodeValues(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Specify whether the user wants to see bookmarks or not
     * 
     * @param p_key User's security key
     * @param p_showBookmarks Do we want to see bookmarks or not?
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void setShowBookmarks(KeySession p_key, Boolean p_showBookmarks) 
        throws InvalidKeyException {
        try {
            if (!p_key.isValid())
                throw new InvalidKeyException();
        }
        catch(RemoteException e) {
             throw new InvalidKeyException();
        }
        KeySessionLocal keyLocal = getKeyLocal(p_key);
        keyLocal.getUserLocal().setShowBookmarks(p_showBookmarks);
    }
    
    /**
     * If the user has a valid login key then add a bookmark node.
     * 
     * @param p_key User's security key
     * @param p_node The node to be bookmarked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void addBookmarkNode(KeySession p_key,
                                NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            UserSessionUtil.getLocalHome().create().addBookmarkNode(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid login key then remove a bookmark node.
     * 
     * @param p_key User's security key
     * @param p_node The node to be bookmarked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void removeBookmarkNode(KeySession p_key,
                                   NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            UserSessionUtil.getLocalHome().create().removeBookmarkNode(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of node links that can be seen by this user from the 
     * specified node.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of node links that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getNodeLinkValues(KeySession p_key,
                                                  NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TreeSessionUtil.getLocalHome().create().getNodeLinkValues(keyLocal, nodeLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of task dependencies that can be seen by this user from the 
     * specified node.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of task dependencies that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getTaskDependencyValues(KeySession p_key,
                                                        NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TaskSessionUtil.getLocalHome().create().getTaskDependencyValues(keyLocal, nodeLocal.getTaskLocal());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Gets a list of task dependencies that can be seen by this user from the 
     * specified node.
     * 
     * @param p_key User's security key
     * @param p_node Current node for which the links will be found
     * @return A collection of task dependencies that are visible from the specified node
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getTaskDependantValues(KeySession p_key,
                                                       NodePK p_nodePK) 
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            return TaskSessionUtil.getLocalHome().create().getTaskDependantValues(keyLocal, nodeLocal.getTaskLocal());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get a tree model of tasks rooted at the specified task with given depth
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public javax.swing.tree.TreeModel getTaskValueTree(com.velocityme.interfaces.KeySession p_key,
                                                       com.velocityme.interfaces.TaskPK p_taskPK,
                                                       int p_depth) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskLocal taskLocal = TaskUtil.getLocalHome().findByPrimaryKey(p_taskPK);
            return TaskSessionUtil.getLocalHome().create().getTaskValueTree(keyLocal, taskLocal, p_depth);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Checks to see if it is a legal paste node
     *
     * @param p_key User's security key
     * @param p_target The target node to which the node will be moved
     * @param p_child The node that is to be moved
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isValidPasteNode(KeySession p_key, NodePK p_targetPK, NodePK p_childPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal targetLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_targetPK);
            NodeLocal childLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_childPK);
            return TreeSessionUtil.getLocalHome().create().isValidPasteNode(keyLocal, targetLocal, childLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Checks to see if it is a legal link node
     *
     * @param p_key User's security key
     * @param p_target The target node to which the node will be linked
     * @param p_child The node that is to be linked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isValidLinkNode(KeySession p_key, NodePK p_targetPK, NodePK p_markedPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal targetLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_targetPK);
            NodeLocal markedLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_markedPK);
            return TreeSessionUtil.getLocalHome().create().isValidLinkNode(keyLocal, targetLocal, markedLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Checks to see if it is a legal dependency pair
     *
     * @param p_key User's security key
     * @param p_dependency The target node to which the node will be linked
     * @param p_dependant The node that is to be linked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isValidDependencyPair(KeySession p_key, NodePK p_dependencyPK, NodePK p_dependantPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal dependencyLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_dependencyPK);
            NodeLocal dependantLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_dependantPK);
            return TaskSessionUtil.getLocalHome().create().isValidDependencyPair(keyLocal, dependencyLocal.getTaskLocal(), dependantLocal.getTaskLocal());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Moves the node in the tree to the target node
     *
     * @param p_key User's security key
     * @param p_target The target node to which the node will be moved
     * @param p_child The node that is to be moved
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void moveChildNode(KeySession p_key, NodePK p_targetPK, NodePK p_childPK)
        throws InvalidKeyException, PermissionDeniedException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal targetLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_targetPK);
            NodeLocal childLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_childPK);
            TreeSessionUtil.getLocalHome().create().moveChildNode(keyLocal, targetLocal, childLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Links the node in the tree to the target node
     *
     * @param p_key User's security key
     * @param p_target The target node to which the node will be moved
     * @param p_marked The node that is to be linked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void createNodeLink(KeySession p_key, NodePK p_targetPK, NodePK p_markedPK)
        throws InvalidKeyException, PermissionDeniedException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal targetLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_targetPK);
            NodeLocal markedLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_markedPK);
            TreeSessionUtil.getLocalHome().create().createNodeLink(keyLocal, targetLocal, markedLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Create a dependency between two tasks
     *
     * @param p_key User's security key
     * @param p_dependency The target node to which the node will be moved
     * @param p_dependant The node that is to be linked
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void createTaskDependency(KeySession p_key, NodePK p_dependencyPK, NodePK p_dependantPK)
        throws InvalidKeyException, PermissionDeniedException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal dependencyLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_dependencyPK);
            NodeLocal dependantLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_dependantPK);
            TaskSessionUtil.getLocalHome().create().createTaskDependency(keyLocal, dependencyLocal.getTaskLocal(), dependantLocal.getTaskLocal());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Delete the link between a pair of nodes in the tree
     *
     * @param p_key User's security key
     * @param p_node1 The first node of the pair
     * @param p_node2 The second node of the pair
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void nodeLinkDelete(KeySession p_key, NodeLinkPK p_nodeLinkPK)
        throws InvalidKeyException, PermissionDeniedException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLinkLocal nodeLinkLocal = NodeLinkUtil.getLocalHome().findByPrimaryKey(p_nodeLinkPK);
            TreeSessionUtil.getLocalHome().create().deleteNodeLink(keyLocal, nodeLinkLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
     /**
     * Delete the dependency between a pair of tasks in the tree
     *
     * @param p_key User's security key
     * @param p_taskDependency The task pair
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void taskDependencyDelete(KeySession p_key, TaskDependencyPK p_taskDependencyPK)
        throws InvalidKeyException, PermissionDeniedException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            TaskDependencyLocal taskDependencyLocal = TaskDependencyUtil.getLocalHome().findByPrimaryKey(p_taskDependencyPK);
            TaskSessionUtil.getLocalHome().create().deleteTaskDependency(keyLocal, taskDependencyLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new UserAccess in the specified 
     * node then go ahead and create it.
     *
     * @param p_key User's security key
     * @param p_nodePK The node in which the user access will be created
     * @param p_value The UserAccess value object
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.UserAccessPK userAccessCreate(com.velocityme.interfaces.KeySession p_key,
                                                                   com.velocityme.interfaces.NodePK p_nodePK,
                                                                   com.velocityme.interfaces.UserPK p_userPK,
                                                                   com.velocityme.interfaces.RolePK p_rolePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            RoleLocal roleLocal = RoleUtil.getLocalHome().findByPrimaryKey(p_rolePK);
            UserAccessLocal userAccessLocal = UserAccessSessionUtil.getLocalHome().create().createUserAccess(keyLocal, nodeLocal, userLocal, roleLocal);
            return new UserAccessPK(userAccessLocal.getUserAccessId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to delete the user access then do so .
     *
     * @param p_key User's security key
     * @param p_userAccess The UserAccess object being deleted
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void userAccessDelete(com.velocityme.interfaces.KeySession p_key, 
                                 com.velocityme.interfaces.UserAccessPK p_userAccessPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            UserAccessLocal userAccessLocal = UserAccessUtil.getLocalHome().findByPrimaryKey(p_userAccessPK);
            UserAccessSessionUtil.getLocalHome().create().deleteUserAccess(keyLocal, userAccessLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission then get a list of accesses by user.
     *
     * @param p_key User's security key
     * @param p_userPK The User whose access list is required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getUserAccessByUserValue(com.velocityme.interfaces.KeySession p_key,
                                                         com.velocityme.interfaces.UserPK p_userPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            return UserAccessSessionUtil.getLocalHome().create().findByUserValue(keyLocal, userLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission then get a list of accesses by node.
     *
     * @param p_key User's security key
     * @param p_node The Node whose access list is required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getUserAccessByNodeValue(com.velocityme.interfaces.KeySession p_key,
                                                         com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            NodeLocal parentNodeLocal = nodeLocal.getParentNodeLocal();
            UserAccessSessionLocal userAccessSessionLocal = UserAccessSessionUtil.getLocalHome().create();
            Collection accesses = userAccessSessionLocal.findByNodeValue(keyLocal, nodeLocal);
            while(parentNodeLocal != null) {
                accesses.addAll(userAccessSessionLocal.findByNodeValue(keyLocal, parentNodeLocal));
                parentNodeLocal = parentNodeLocal.getParentNodeLocal();
            }
            return accesses;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new GroupAccess in the specified 
     * node then go ahead and create it.
     *
     * @param p_key User's security key
     * @param p_nodePK The node in which the user access will be created
     * @param p_value The GroupAccess value object
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.GroupAccessPK groupAccessCreate(com.velocityme.interfaces.KeySession p_key,
                                                                     com.velocityme.interfaces.NodePK p_nodePK,
                                                                     com.velocityme.interfaces.GroupPK p_groupPK,
                                                                     com.velocityme.interfaces.RolePK p_rolePK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            GroupLocal groupLocal = GroupUtil.getLocalHome().findByPrimaryKey(p_groupPK);
            RoleLocal roleLocal = RoleUtil.getLocalHome().findByPrimaryKey(p_rolePK);
            GroupAccessLocal groupAccessLocal = GroupAccessSessionUtil.getLocalHome().create().createGroupAccess(keyLocal, nodeLocal, groupLocal, roleLocal);
            return new GroupAccessPK(groupAccessLocal.getGroupAccessId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to delete the user access then do so .
     *
     * @param p_key User's security key
     * @param p_groupAccess The GroupAccess object being deleted
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void groupAccessDelete(com.velocityme.interfaces.KeySession p_key, 
                                  com.velocityme.interfaces.GroupAccessPK p_groupAccessPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            GroupAccessLocal groupAccessLocal = GroupAccessUtil.getLocalHome().findByPrimaryKey(p_groupAccessPK);
            GroupAccessSessionUtil.getLocalHome().create().deleteGroupAccess(keyLocal, groupAccessLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission then get a list of accesses by group.
     *
     * @param p_key User's security key
     * @param p_groupPK The Group whose access list is required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getGroupAccessByUserValue(com.velocityme.interfaces.KeySession p_key,
                                                          com.velocityme.interfaces.GroupPK p_groupPK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            GroupLocal groupLocal = GroupUtil.getLocalHome().findByPrimaryKey(p_groupPK);
            return GroupAccessSessionUtil.getLocalHome().create().findByGroupValue(keyLocal, groupLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission then get a list of accesses by node.
     *
     * @param p_key User's security key
     * @param p_node The Node whose access list is required
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getGroupAccessByNodeValue(com.velocityme.interfaces.KeySession p_key,
                                                          com.velocityme.interfaces.NodePK p_nodePK)
        throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal nodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_nodePK);
            NodeLocal parentNodeLocal = nodeLocal.getParentNodeLocal();
            GroupAccessSessionLocal groupAccessSessionLocal = GroupAccessSessionUtil.getLocalHome().create();
            Collection accesses = groupAccessSessionLocal.findByNodeValue(keyLocal, nodeLocal);
            while(parentNodeLocal != null) {
                accesses.addAll(groupAccessSessionLocal.findByNodeValue(keyLocal, parentNodeLocal));
                parentNodeLocal = parentNodeLocal.getParentNodeLocal();
            }
            return accesses;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new User in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new User
     * @param p_userValue The value details for the User part of the user
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.UserPK userCreate(KeySession p_key,
                                                       NodePK p_parentNodePK,
                                                       com.velocityme.valueobjects.UserValue p_userValue,
                                                       java.lang.String p_password)
        throws PermissionDeniedException, InvalidKeyException, DuplicateUserException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            UserLocal userLocal = UserSessionUtil.getLocalHome().create().createUser(keyLocal, parentNodeLocal, p_userValue, p_password);
            return new UserPK(userLocal.getUserId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the user then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_user The User object being editted
     * @param p_userValue The value details for the User part of the user
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void userEdit(KeySession p_key,
                         UserPK p_userPK,
                         com.velocityme.valueobjects.UserValue p_userValue)
        throws PermissionDeniedException, InvalidKeyException, DuplicateUserException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            UserSessionUtil.getLocalHome().create().editUser(keyLocal, userLocal, p_userValue);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to change the password then do so and log the
     * change with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_user The User object being editted
     * @param p_oldPassword The current password
     * @param p_newPassword The new password
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void userChangePassword(KeySession p_key,
                                   UserPK p_userPK,
                                   String p_oldPassword,
                                   String p_newPassword)
        throws PermissionDeniedException, InvalidKeyException, PasswordIncorrectException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            UserSessionUtil.getLocalHome().create().changePassword(keyLocal, userLocal, p_oldPassword, p_newPassword);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to set enabled then do so and log the
     * change with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_user The User object being editted
     * @param p_enabled The new enabled status
     * @param p_newPassword The new password
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void userSetEnabled(KeySession p_key,
                               UserPK p_userPK,
                               Boolean p_enabled)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            UserSessionUtil.getLocalHome().create().setEnabled(keyLocal, userLocal, p_enabled);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the user value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_userPK The User primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.UserValue getUserValue(KeySession p_key,
                                                             UserPK p_userPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            UserLocal userLocal = UserSessionUtil.getLocalHome().create().getUserLocal(getKeyLocal(p_key), p_userPK);
            return userLocal.getUserValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then determine if the user corresponding to 
     * the specified primary key is enabled.
     *
     * @param p_key User's security key
     * @param p_userPK The User primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isUserEnabled(KeySession p_key,
                                 UserPK p_userPK)
        throws InvalidKeyException {
        try {
            UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
            return userLocal.getIsEnabled().booleanValue();                
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the user login values corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_userPK The User primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getUserLoginValues(KeySession p_key,
                                                   UserPK p_userPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            UserLocal userLocal = UserSessionUtil.getLocalHome().create().getUserLocal(p_key.getLocal(), p_userPK);
            List loginsLocal = new ArrayList(userLocal.getLoginsLocal());
            Collections.sort(loginsLocal, new Comparator() {
                public int compare(Object o1, Object o2) {
                    return ((LoginLocal)o1).getLoginTime().compareTo(((LoginLocal)o2).getLoginTime());
                }
            });
            Collection loginsValue = new ArrayList();
            Iterator i = loginsLocal.iterator();
            while(i.hasNext()) {
                LoginLocal loginLocal = (LoginLocal)i.next();
                loginsValue.add(loginLocal.getLoginValue());
            }
            return loginsValue;
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(RemoteException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the all the user login values.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllUserLoginValues(KeySession p_key)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            List loginsLocal = new ArrayList(LoginUtil.getLocalHome().findAll());
            Collections.sort(loginsLocal, new Comparator() {
                public int compare(Object o1, Object o2) {
                    return ((LoginLocal)o1).getLoginTime().compareTo(((LoginLocal)o2).getLoginTime());
                }
            });
            Collection loginsValue = new ArrayList();
            Iterator i = loginsLocal.iterator();
            while(i.hasNext()) {
                LoginLocal loginLocal = (LoginLocal)i.next();
                loginsValue.add(loginLocal.getLoginValue());
            }
            return loginsValue;
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the person value object corresponding
     * to the specified user primary key.
     *
     * @param p_key User's security key
     * @param p_userPK The User primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.PersonValue getUserPersonValue(KeySession p_key,
                                                                      UserPK p_userPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                UserLocal userLocal = UserUtil.getLocalHome().findByPrimaryKey(p_userPK);
                return userLocal.getPersonLocal().getPersonValue();
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the group value objects corresponding
     * to the specified user primary key.
     *
     * @param p_key User's security key
     * @param p_userPK The User primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getUserGroupValues(KeySession p_key,
                                                   UserPK p_userPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                Collection groupValues = new ArrayList();
                Iterator i = UserUtil.getLocalHome().findByPrimaryKey(p_userPK).getGroupsLocal().iterator();
                while(i.hasNext()) {
                    groupValues.add(((GroupLocal)i.next()).getGroupValue());
                }
                return groupValues;
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of user value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllUserValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return UserSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to create a new Group in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new User
     * @param p_groupValue The value details for the Group part of the group
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.interfaces.GroupPK groupCreate(KeySession p_key,
                                                         NodePK p_parentNodePK,
                                                         com.velocityme.valueobjects.GroupValue p_groupValue,
                                                         java.util.Collection p_usersPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            NodeLocal parentNodeLocal = NodeUtil.getLocalHome().findByPrimaryKey(p_parentNodePK);
            Collection usersLocal = new ArrayList();
            Iterator i = p_usersPK.iterator();
            while(i.hasNext()) {
                usersLocal.add(UserUtil.getLocalHome().findByPrimaryKey((UserPK)i.next()));
            }
            GroupLocal groupLocal = GroupSessionUtil.getLocalHome().create().createGroup(keyLocal, parentNodeLocal, p_groupValue, usersLocal);
            return new GroupPK(groupLocal.getGroupId());
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the group then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_group The Group object being editted
     * @param p_groupValue The value details for the Group part of the group
     *
     * @ejb.interface-method view-type="remote"
     **/
    public void groupEdit(KeySession p_key,
                          GroupPK p_groupPK,
                          com.velocityme.valueobjects.GroupValue p_groupValue,
                          java.util.Collection p_usersPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            GroupLocal groupLocal = GroupUtil.getLocalHome().findByPrimaryKey(p_groupPK);
            Collection usersLocal = new ArrayList();
            Iterator i = p_usersPK.iterator();
            while(i.hasNext()) {
                usersLocal.add(UserUtil.getLocalHome().findByPrimaryKey((UserPK)i.next()));
            }
            GroupSessionUtil.getLocalHome().create().editGroup(keyLocal, groupLocal, p_groupValue, usersLocal);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the group value object corresponding
     * to the specified primary key.
     *
     * @param p_key User's security key
     * @param p_groupPK The Group primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public com.velocityme.valueobjects.GroupValue getGroupValue(KeySession p_key,
                                                                GroupPK p_groupPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            GroupLocal groupLocal = GroupSessionUtil.getLocalHome().create().getGroupLocal(getKeyLocal(p_key), p_groupPK);
            return groupLocal.getGroupValue();
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has a valid key then get the user value objects corresponding
     * to the specified group primary key.
     *
     * @param p_key User's security key
     * @param p_groupPK The Group primary key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getGroupUserValues(KeySession p_key,
                                                   GroupPK p_groupPK)
        throws InvalidKeyException {
        try {
            if (getKeyLocal(p_key).isValid()) {
                Collection userValues = new ArrayList();
                Iterator i = GroupUtil.getLocalHome().findByPrimaryKey(p_groupPK).getUsersLocal().iterator();
                while(i.hasNext()) {
                    userValues.add(((UserLocal)i.next()).getUserValue());
                }
                return userValues;
            }
            else
                throw new InvalidKeyException();
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of group value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="remote"
     **/
    public java.util.Collection getAllGroupValues(KeySession p_key) throws InvalidKeyException {
        try {
            KeySessionLocal keyLocal = getKeyLocal(p_key);
            return GroupSessionUtil.getLocalHome().create().getAllValueObjects(keyLocal);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Check if any licences have been installed
     *
     * @ejb.interface-method view-type="remote"
     **/
    public boolean isLicenceInstalled() {
        try {
            return SetupSessionUtil.getLocalHome().create().isLicenceInstalled();
        } catch(CreateException e) {
            throw new EJBException(e);
        } catch(NamingException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Create the Session Bean.
     * @throws CreateException 
     * @ejb:create-method view-type="remote"
     */
    public void ejbCreate() throws CreateException {
    }

    public void ejbActivate() throws java.rmi.RemoteException {
    }
    
    public void ejbPassivate() throws java.rmi.RemoteException {
    }
    
    public void ejbRemove() throws java.rmi.RemoteException {
    }
    
    public void setSessionContext(javax.ejb.SessionContext sessionContext) throws java.rmi.RemoteException {
        m_context = sessionContext;
    }
    
}
